package com.yykj.common.service.impl;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.tencentyun.TLSSigAPIv2;
import com.yykj.common.bean.*;
import com.yykj.common.config.ProjectConfig;
import com.yykj.common.dto.*;
import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import com.yykj.common.service.TencentService;
import com.yykj.common.util.JsonUtil;
import com.yykj.common.util.LocalMathUtil;
import com.yykj.common.util.LocalObjectUtil;
import com.yykj.common.util.LocalStringUtil;
import com.yykj.common.vo.SendMessageRetVO;
import com.yykj.common.vo.TencentUserRetVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author chenl
 */
@Slf4j
@Service
public class TencentServiceImpl implements TencentService {
    public static final String ADMINISTRATOR = "administrator";

    private static final String SYSTEM = "system";

    private static TLSSigAPIv2 api;

    String domain = "https://console.tim.qq.com/v4/";

    @Override
    public CreateAccountDTO createAccount(String identifier, String nick, String faceUrl) {
        String url = "https://console.tim.qq.com/v4/im_open_login_svc/account_import";

        Map<String, String> param = new HashMap<String, String>();
        param.put("Identifier", identifier);
        param.put("Nick", nick);
        param.put("FaceUrl", faceUrl);

        try {
            String s = doPost(url, JsonUtil.toJson(param));
            CreateAccountDTO createAccountDTO = JsonUtil.fromJson(s, CreateAccountDTO.class);

            if (createAccountDTO != null && createAccountDTO.getErrorCode() == 0) {
                log.info("createAccountDTO = {}", createAccountDTO);
                return createAccountDTO;
            }
            if (createAccountDTO != null) {
                throw new NormalException(ResultEnums.CREATE_ACCOUNT_ERROR, createAccountDTO.getErrorInfo());
            } else {
                throw new NormalException(ResultEnums.CREATE_ACCOUNT_ERROR);
            }

        } catch (UnirestException e) {
            throw new NormalException(ResultEnums.REQUEST_URL_ERROR);
        }
    }

    @Override
    public void portraitSet(TencentUser tencentUser) {
        String url = "https://console.tim.qq.com/v4/profile/portrait_set";
        if (StringUtils.isEmpty(tencentUser.getAccid())) {
            throw new NormalException(ResultEnums.PARAM_ERROR);
        }
        Map<String, String> dataMap = LocalObjectUtil.objectToStringStringMap(tencentUser, false);
        if (dataMap.size() > 1) {
            TencentUserPostDTO postDTO = new TencentUserPostDTO();
            postDTO.setFrom_Account(tencentUser.getAccid());
            for (String key : dataMap.keySet()) {
                if ("accid".equals(key)) {
                    continue;
                }
                ProfileItem item = new ProfileItem();
                item.setTag(key);
                item.setValue(dataMap.get(key));
                postDTO.getProfileItem().add(item);
            }

            try {
                String s = doPost(url, JsonUtil.toJson(postDTO));
                System.out.println(s);
            } catch (UnirestException e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    public TencentUser getTencentUserInfo(String accid) {
        String url = "https://console.tim.qq.com/v4/profile/portrait_get";
        TencentUser tencentUser = new TencentUser();
        tencentUser.setAccid(accid);
        List<String> tagList = new ArrayList<>();
        Map<String, String> dataMap = LocalObjectUtil.objectToStringStringMap(tencentUser, true);
        for (String key : dataMap.keySet()) {
            if ("accid".equals(key)) {
                continue;
            }
            tagList.add(key);
        }
        TencentUserInfoPostDTO postDTO = new TencentUserInfoPostDTO();
        postDTO.setTo_Account(Collections.singletonList(accid));
        postDTO.setTagList(tagList);
        String s = null;
        try {
            s = doPost(url, JsonUtil.toJson(postDTO));
        } catch (UnirestException e) {
            e.printStackTrace();
        }
        System.out.println(s);
        TencentUserRetVO tencentUserRetVO = JsonUtil.fromJson(s, TencentUserRetVO.class);
        if (tencentUserRetVO.getErrorCode() != 0) {
            throw new NormalException(ResultEnums.TENCENT_USER_INFO_ERROR,
                    ResultEnums.TENCENT_USER_INFO_ERROR.getMessage() + tencentUserRetVO.getErrorInfo());
        }
        for (UserProfileItem userProfileItem : tencentUserRetVO.getUserProfileItem()) {
            for (ProfileItem profileItem : userProfileItem.getProfileItem()) {
                for (Field field : tencentUser.getClass().getDeclaredFields()) {
                    if (field.getName().equals(profileItem.getTag())) {
                        field.setAccessible(true);
                        try {
                            field.set(tencentUser, profileItem.getValue());
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return tencentUser;
    }

    private String doPost(String url, String body) throws UnirestException {
        url += "?sdkappid=" + ProjectConfig.tencentAppId +
                "&identifier=" + ADMINISTRATOR +
                "&usersig=" + getUserSign(ADMINISTRATOR) +
                "&random=" + LocalMathUtil.randomInt() +
                "&contenttype=json";
        HttpResponse<String> response = Unirest.post(url)
                .header("accept", "application/json")
                .header("content-type", "application/json")
                .body(body).asString();
        return response.getBody();
    }

    public String getUserSign(String identifier, Integer expire) {
        if (api == null) {
            api = new TLSSigAPIv2(ProjectConfig.tencentAppId, ProjectConfig.tencentAppSecret);
        }
        return api.genSig(identifier, expire);
    }

    public String getUserSign(String identifier) {
        return getUserSign(identifier, 7 * 86400);//7天
    }

    @Override
    public String getAudioSign(String accid) {
        return getAudioSign(accid, 7 * 86400);//7天
    }

    @Override
    public void sendNotifyMessage(NotifyMessageDTO notifyMessageDTO) {
        log.info("【发送通知消息】参数:{}", JsonUtil.toJson(notifyMessageDTO));
        String url = "https://console.tim.qq.com/v4/openim/sendmsg";
        String s = null;
        SendMessageRetVO sendMessageRetVO = null;
        try {
            s = doPost(url, JsonUtil.toJson(notifyMessageDTO));
            sendMessageRetVO = JsonUtil.fromJson(s, SendMessageRetVO.class);
            log.info("【发送通知消息】返回:{}", JsonUtil.toJson(sendMessageRetVO));
        } catch (UnirestException e) {
            e.printStackTrace();
        }
        if (null != sendMessageRetVO && !"0".equals(sendMessageRetVO.getErrorCode())) {
            throw new NormalException(ResultEnums.NOTIFY_MESSAGE_ERROR, sendMessageRetVO.getErrorInfo());
        }
    }

    @Override
    public void sendCustomMessage(String fromAccid, String toAccid, TIMCustomElemContent customElemContent) {
        NotifyMsgContent notifyMsgContent = new NotifyMsgContent();

        notifyMsgContent.setMsgContent(customElemContent);
        notifyMsgContent.setMsgType("TIMCustomElem");
        if (StringUtils.isEmpty(fromAccid)) {
            fromAccid = ProjectConfig.adminAccid;
        }

        NotifyMessageDTO notifyMessageDTO = NotifyMessageDTO.builder()
                .SyncOtherMachine(1)
                .From_Account(fromAccid)
                .To_Account(toAccid)
                .MsgRandom(LocalMathUtil.randomInt())
                .MsgTimeStamp(LocalStringUtil.getCurrentTimeInt())
                .MsgBody(Collections.singletonList(notifyMsgContent))
                .build();
        log.info("请求数据:{}", JsonUtil.toJson(notifyMessageDTO));
        this.sendNotifyMessage(notifyMessageDTO);
    }

    public String getAudioSign(String identifier, Integer expire) {
        if (api == null) {
            api = new TLSSigAPIv2(ProjectConfig.tencentAudioAppId, ProjectConfig.tencentAudioAppSecret);
        }
        return api.genSig(identifier, expire);
    }

    @Override
    public GetFriendDTO getFriend(String userId) {
        String url = domain + "sns/friend_get";
        Map<String, Object> param = new HashMap<>();
        param.put("From_Account", userId);
        param.put("StartIndex", 0);
        param.put("StandardSequence", 0);
        param.put("CustomSequence", 0);
        try {
            String s = doPost(url, JsonUtil.toJson(param));
            GetFriendDTO getFriendDTO = JsonUtil.fromJson(s, GetFriendDTO.class);
            if (getFriendDTO != null && getFriendDTO.getErrorCode() == 0) {
                log.info("GetFriendDTO = {}", getFriendDTO);
                return getFriendDTO;
            }
        } catch (Exception e) {
            log.info("GetFriendDTO exception = {}", e);
        }
        return null;
    }
}